var web = web || {};
web.FormSelect = Class.create(); 
web.FormSelect.prototype = {
	initialize: function(obj, css) {
		if (!obj.is('div') || !obj.hasClass(css.skin)) return;
		
		this.css = css;
		this.select = obj;
		this.input = obj.children('input');
		this.box = obj.children('.select_input');
		this.option = obj.children('.select_options');
		
		this._init();
	},
	show: function() {
		var v = this.input.val();
		this.select.removeClass(this.css.over).addClass(this.css.focus);
		if (v != '') {
			this.option.find('li.selected').removeClass('selected');
			this.option.find('li[val="'+ v +'"]').addClass('selected');
		}
		
		this.option.show();
	},
	hide: function() {
		if (this.option.is(':visible')) {
			this.select.removeClass(this.css.focus).addClass(this.css.over);
			this.option.hide();
		}
	},
	clear: function() {
	
	},
	add: function() {
		
	},
	remove: function() {
		
	},
	_init: function() {
		var _this = this;
		
		this.box.bind('click', function(){
			if (_this.select.hasClass(_this.css.focus)) {
				_this.hide();
			} else {
				_this.show();
			}
		});
		
		this.select.bind('mouseup', function(event) {
			if (_this.option.is(':visible')) {
				event.stopPropagation();
			}
		});
		
		$(document).bind('mouseup', function() {
			_this.hide();
			_this.select.removeClass(_this.css.over); 
		});
		
		this.option.find('li').bind('mouseenter mouseleave', function() {
			var li = $(this);
			if (!li.hasClass('selected')) {
				li.toggleClass('over');
			}
		}).bind('click', function(){
			var li = $(this);
			_this.input.val(li.attr('val'));
			_this.box.children('span').html(li.html());
			_this.hide();
		});
	}	
};

var web = web || {};
web.PasswordStrength = Class.create(); 
web.PasswordStrength.prototype = {
	initialize: function(pas, options) {
		this.settings = $.extend({
			css: ['is10', 'is20', 'is30', 'is40', 'is50', 'is60', 'is70', 'is80', 'is90', 'is100'],
			result: '#div_password_strength',
			cache: {}
		}, options);
		
		this.password = pas;
		this.result = $(this.settings.result);
		
		this.defaultCss = this.result.attr('class');
		this.percents = (this.settings.css.length) ? 100 / this.settings.css.length : 100;
		
		if ((this.password.size() == 1) && this.password.is("input[type='password']") && (this.result.size() == 1)) {
			this._init();
		}
	},
	_init: function() {
		var _this = this;
		this.password.bind('keyup', function(){
			var s = _this._getPasswordStrength(this.value);
			var t = Math.floor( s / _this.percents );
			if (100 <= s) t = _this.settings.css.length - 1;
			_this.result.removeClass().addClass(_this.defaultCss).addClass(_this.settings.css[t]);
			return false;
		});
	},
	_getPasswordStrength: function(password) {
		var d = password.length;
		if (d > 5) d = 5;
		
		var g = (password.length - password.replace(/[0-9]/g, '').length);
		if (g > 3) g = 3;
		
		var c = (password.length - password.replace(/\W/g, '').length);
		if (c > 3) c = 3;
		
		var i = (password.length - password.replace(/[A-Z]/g, '').length);
		if (i > 3) i = 3;
		
		var e = ((d * 10) - 20) + (g * 10) + (c * 15) + (i * 10);
		if (e < 0) e = 0;
		if (e > 100) e = 100;

		return e;
	}
};


web.FormUI = Class.create(); 
web.FormUI.prototype = {
	initialize: function(options) {
		var defaults = {
			css: {
				select: {skin:'form_select', over:'f_s_over', focus:'f_s_focus'}, 
				checkbox: {skin:'form_checkbox', checked:'checked', over:'over', checked_over:'checked_over'}, 
				radio: {skin:'form_radio', checked:'checked', over:'over', checked_over:'checked_over'},
				spinbox: {skin:'form_spinbox'},
				over: {skin:'has_over', over:'form_over', focus:'form_focus'}
			}
		};

		this.settings = $.extend(defaults, options);
		this.form = null;
		this.selects = null;
		this.checkboxs = null;
		this.radios = null;
		this.spinboxs = null;
	},
	ui: function(elem) {
		var _this = this;
		if (0 == elem.size()) return;
		
		this.form = elem;
		this.selects = this.form.find('.'+ this.settings.css.select.skin);
		this.checkboxs = this.form.find('.'+ this.settings.css.checkbox.skin);
		this.radios = this.form.find('.'+ this.settings.css.radio.skin);
		this.spinboxs = this.form.find('.'+ this.settings.css.spinbox.skin);
		
		this._init();
		
	},
	_init: function() {
		this._initSelects();
		this._initCheckboxs();
		this._initRadios();
		this._initSpinbox();
		
		var overs = this.form.find('.'+ this.settings.css.over.skin);
		this._bindMouseEnvents(overs, null, this.settings.css.over);
	},
	_initSpinbox: function() {
		var _this = this;
		this.spinboxs.each(function(){
			var spinbox = $(this);
			var i = spinbox.find('input');
			var t = Number(i.attr('setp')), m = Number(i.attr('max')), s = Number(i.attr('min'));
			if (isNaN(t) || isNaN(m) || isNaN(s)) return;
			var pos = t.toString().lastIndexOf('.');
			var l = (pos != -1) ? t.toString().length - pos - 1 : 0;
			
			spinbox.find('.up').bind('click', function(){
				_this._changeSpinboxVal(i, t, m, s, l);
				return false;
			});
			
			spinbox.find('.down').bind('click', function(){
				_this._changeSpinboxVal(i, (0-t), m, s, l);
				return false;
			});
		});
	},
	_changeSpinboxVal: function(i, t, m, s, l) {
		var v = Number(i.val());
		if (isNaN(v)) return;
		v += t;
		v = (l == 0) ? parseInt(v) : v.toFixed(l);
		if ((v >= s) && (v <= m)) i.val(v);
	},
	_initSelects: function() {
		var _this = this;
		this._bindMouseEnvents(this.selects);
		this.selects.each(function(){
			new web.FormSelect($(this), _this.settings.css.select);
		});
	},
	_initCheckboxs: function() {
		var _this = this;
		this.checkboxs.each(function(){
			var lables = $(this).find('label');
			lables.bind('click', function(){
				_this._checkboxClick($(this), _this.settings.css.checkbox);
				return false;
			});
			_this._bindMouseEnvents(lables, _this.checkboxs);
		});
	},
	_initRadios: function() {
		var _this = this;
		this.radios.each(function(){
			var radio = $(this);
			var lables = radio.find('label');
			_this._bindMouseEnvents(lables, _this.radios);
			lables.bind('click', function(){
				_this._radioClick(radio, $(this), _this.settings.css.radio);
				return false;
			});
		});
	},
	_radioClick: function(radio, lable, css) {
		var input = lable.children('input');
		var span = lable.children('span');
		
		if (span.hasClass(css.checked)) return;
		var checked = radio.find('span.'+ css.checked);
		if (checked.size() > 0) {
			checked.removeClass();
			checked.parent().children('input').attr('checked', '');
		}
		
		span.removeClass().addClass(css.checked);
		input.attr('checked', true);
	},
	_checkboxClick: function(lable, css) {
		var input = lable.children('input');
		var span = lable.children('span');
		
		if (span.hasClass(css.checked)) {
			span.removeClass().addClass(css.over);
			input.attr('checked', '');
		} else {
			span.removeClass().addClass(css.checked).addClass(css.checked_over);
			input.attr('checked', true);
		}
	},
	_bindMouseEnvents: function(elems, parent, css) {
		var _this = this;
		var c = css || this._getElementCss((parent || elems));
		if (!c) return;
		elems.bind({
			mouseenter: function(){_this._mouseOver($(this), c);},
			mouseleave: function(){_this._mouseOut($(this), c);}
		});
	},
	_mouseOver: function(elem, css) {
		if (elem.is('label')) {
			var span = elem.children('span');
			if (span.size() > 0) {
				var c = span.hasClass(css.checked) ? css.checked_over : css.over;
				span.addClass(c);
			}
		} else {
			if (!elem.hasClass(css.focus)) {;
				elem.addClass(css.over);
			}
		}
	},
	_mouseOut: function(elem, css) {
		if (elem.is('label')) {
			var span = elem.children('span');
			if (span.size() > 0) {
				var c = span.hasClass(css.checked) ? css.checked_over : css.over;
				span.removeClass(c);
			}
		} else {
			if (!elem.hasClass(css.focus)) {
				elem.removeClass(css.over);
			}
		}
	},
	_getElementCss: function(elem) {
		var css = null;
		if (elem.hasClass(this.settings.css.select.skin)) {
			css = this.settings.css.select;
		} else if (elem.hasClass(this.settings.css.checkbox.skin)) {
			css = this.settings.css.checkbox;
		} else if (elem.hasClass(this.settings.css.radio.skin)) {
			css = this.settings.css.radio;
		}
		return css;
	}
};

(function($){  
	$.fn.formUI = function(options){
		return this.each(function(){
			var from = new web.FormUI(options);
			from.ui($(this));
		});
	};
	
	$.fn.passwordStrength = function(options){
		return this.each(function(){
			new web.PasswordStrength($(this), options);
		});
	};
})(jQuery); 